#!/usr/bin/python3
"""List the packages which could be automatically installed without becoming autoremovable

Finds all manually installed meta packages, and prints their dependencies
which could be marked as automatically installed.
"""
import sys

import apt


def is_root(pkg):
    """Check if the package is a root package (manually inst. meta)"""
    section = pkg.candidate.section if pkg.candidate else ""
    return (pkg.is_installed and
            not pkg.is_auto_installed and
            (section == "metapackages" or
             section.endswith("/metapackages")))


def main():
    """Main function"""
    cache = apt.Cache(rootdir=sys.argv[1] if len(sys.argv) > 1 else None)
    roots = set(pkg for pkg in cache if is_root(pkg))
    workset = set(roots)
    seen = set()
    ubiquity_depends = set()

    with cache.actiongroup():
        while True:
            print("Iteration", file=sys.stderr)
            to_proc = workset - seen
            if not to_proc:
                break
            for pkg in sorted(to_proc):
                print("    Visiting", pkg, file=sys.stderr)

                if pkg not in roots and pkg not in ubiquity_depends:
                    if not pkg.is_auto_installed:
                        print(pkg.name)

                for dep in (pkg.installed.dependencies +
                            pkg.installed.recommends):
                    for bdep in dep.or_dependencies:
                        for ver in bdep.target_versions:
                            if ver.package.is_installed:
                                if pkg.name == "ubiquity":
                                    ubiquity_depends.add(ver.package)
                                if pkg.name != "ubiquity":
                                    # Reprocess this package again, as we did not mark it when we visited it from ubiquity
                                    try:
                                        ubiquity_depends.remove(ver.package)
                                        # This will raise the KeyError here if ubiquity did not depend on it
                                        seen.remove(ver.package)
                                    except KeyError:
                                        pass
                                workset.add(ver.package)

                seen.add(pkg)


if __name__ == '__main__':
    main()
